<template>
  <div class="menu-management">
    <el-card shadow="never">
      <!-- 顶部工具栏 -->
      <div class="toolbar">
        <div class="toolbar-left">
          <el-input
            v-model="query.keyword"
            placeholder="搜索菜单名称"
            style="width: 200px"
            clearable
            @keyup.enter="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
          <el-button type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
          <el-button @click="handleReset">
            <el-icon><Refresh /></el-icon>
            重置
          </el-button>
          <el-button type="primary" @click="handleAdd">
            <el-icon><Plus /></el-icon>
            新增菜单
          </el-button>
          <el-button type="danger" :disabled="!selectedIds.length" @click="handleBatchDelete">
            <el-icon><Delete /></el-icon>
            批量删除
          </el-button>
        </div>

        <div class="toolbar-right">
          <el-button @click="toggleExpandAll">
            <el-icon><Operation /></el-icon>
            {{ isExpandAll ? '收起' : '展开' }}全部
          </el-button>
          <el-button @click="refreshTable">
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </div>

      <!-- 菜单表格 -->
      <el-table
        ref="tableRef"
        :data="filteredTableData"
        v-loading="loading"
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        :default-expand-all="isExpandAll"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />

        <el-table-column prop="name" label="菜单名称" min-width="180">
          <template #default="{ row }">
            <div class="menu-name">
              <el-icon v-if="row.icon" class="menu-icon">
                <component :is="getIconComponent(row.icon)" />
              </el-icon>
              <span>{{ row.name }}</span>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="menuType" label="类型" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="getMenuTypeTagType(row.menuType)" size="small">
              {{ getMenuTypeText(row.menuType) }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column prop="routePath" label="路由路径" min-width="150">
          <template #default="{ row }">
            <el-text v-if="row.routePath" type="primary">{{ row.routePath }}</el-text>
            <el-text v-else type="info" size="small">—</el-text>
          </template>
        </el-table-column>

        <el-table-column prop="component" label="组件路径" min-width="200" show-overflow-tooltip>
          <template #default="{ row }">
            <el-text v-if="row.component" type="info" size="small">
              {{ row.component }}
            </el-text>
            <el-text v-else type="info" size="small">—</el-text>
          </template>
        </el-table-column>

        <el-table-column prop="permissions" label="权限标识" width="140" show-overflow-tooltip>
          <template #default="{ row }">
            <el-tag v-if="row.permissions" size="small" type="info" effect="plain">
              {{ row.permissions }}
            </el-tag>
            <el-text v-else type="info" size="small">—</el-text>
          </template>
        </el-table-column>

        <el-table-column prop="sort" label="排序" width="100" align="center">
          <template #default="{ row }">
            <el-input-number
              v-model="row.sort"
              :min="0"
              :max="999"
              size="small"
              controls-position="right"
              @change="handleSortChange(row)"
              style="width: 90px"
            />
          </template>
        </el-table-column>

        <el-table-column prop="isShow" label="显示" width="80" align="center">
          <template #default="{ row }">
            <el-switch
              v-model="row.isShow"
              @change="handleShowChange(row)"
            />
          </template>
        </el-table-column>

        <el-table-column prop="archive" label="状态" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="row.archive ? 'danger' : 'success'" size="small">
              {{ row.archive ? '归档' : '正常' }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="操作" width="180" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" size="small" text @click="handleEdit(row)">
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-button
              type="primary"
              size="small"
              text
              @click="handleAddChild(row)"
              :disabled="row.menuType === 'BUTTON'"
            >
              <el-icon><Plus /></el-icon>
              新增
            </el-button>
            <el-button type="danger" size="small" text @click="handleDelete(row)">
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="900px"
      :close-on-click-modal="false"
    >
      <el-form
        ref="formRef"
        :model="formModel"
        :rules="formRules"
        label-width="100px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="name">
              <el-input v-model="formModel.name" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group v-model="formModel.menuType">
                <el-radio value="DIRECTORY">目录</el-radio>
                <el-radio value="MENU">菜单</el-radio>
                <el-radio value="BUTTON">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="上级菜单" prop="parentId">
              <el-tree-select
                v-model="formModel.parentId"
                :data="parentMenuOptions"
                placeholder="请选择上级菜单"
                clearable
                check-strictly
                :render-after-expand="false"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="显示排序" prop="sort">
              <el-input-number
                v-model="formModel.sort"
                :min="0"
                :max="999"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20" v-if="formModel.menuType !== 'BUTTON'">
          <el-col :span="12">
            <el-form-item label="路由路径" prop="routePath">
              <el-input
                v-model="formModel.routePath"
                placeholder="请输入路由路径"
                @blur="handleRoutePathBlur"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组件路径" v-if="formModel.menuType === 'MENU'">
              <el-input v-model="formModel.component" placeholder="请输入组件路径">
                <template #append>
                  <el-button @click="autoGenerateComponent">自动生成</el-button>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单图标">
              <el-select v-model="formModel.icon" placeholder="请选择图标" clearable filterable>
                <el-option
                  v-for="icon in iconOptions"
                  :key="icon.value"
                  :label="icon.label"
                  :value="icon.value"
                >
                  <div style="display: flex; align-items: center;">
                    <el-icon style="margin-right: 8px;">
                      <component :is="getIconComponent(icon.value)" />
                    </el-icon>
                    {{ icon.label }}
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限标识">
              <el-input v-model="formModel.permissions" placeholder="请输入权限标识" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20" v-if="formModel.menuType === 'DIRECTORY'">
          <el-col :span="12">
            <el-form-item label="重定向路径">
              <el-input v-model="formModel.redirect" placeholder="请输入重定向路径" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单状态">
              <el-radio-group v-model="formModel.archive">
                <el-radio :value="false">正常</el-radio>
                <el-radio :value="true">归档</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="显示状态">
              <el-radio-group v-model="formModel.isShow">
                <el-radio :value="true">显示</el-radio>
                <el-radio :value="false">隐藏</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <template #footer>
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSave" :loading="saveLoading">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import {
  Search,
  Refresh,
  Plus,
  Delete,
  Edit,
  Operation,
  Setting,
  User,
  House,
  Menu,
  Document,
  Monitor,
  View,
  Connection,
  UserFilled,
  Grid,
  Folder,
  Files,
  DataBoard,
  Management
} from '@element-plus/icons-vue'

// 导入菜单API
import {
  getMenuNodes,
  addMenu,
  updateMenu,
  deleteMenu,
  getParentMenuOptions,
  buildMenuTree,
  transformToFormData,
  generateDefaultComponent,
  validateRoutePath,
  getMenuTypeText,
  getMenuTypeTagType,
  batchDeleteMenus,
  type MenuItem,
  type MenuForm,
  type MenuTreeNode
} from '@/api/menu'

// 响应式数据
const tableRef = ref()
const formRef = ref<FormInstance>()
const loading = ref(false)
const saveLoading = ref(false)
const dialogVisible = ref(false)
const dialogTitle = ref('新增菜单')
const isAdd = ref(true)
const isExpandAll = ref(true)
const selectedIds = ref<number[]>([])

const query = reactive({
  keyword: ''
})

const tableData = ref<MenuItem[]>([])
const parentMenuOptions = ref<MenuTreeNode[]>([])

// 表单数据
const emptyForm: MenuForm = {
  menuType: 'MENU',
  parentId: 0,
  name: '',
  routePath: '',
  component: '',
  permissions: '',
  archive: false,
  icon: '',
  redirect: '',
  isShow: true,
  sort: 0
}

const formModel = reactive<MenuForm>({ ...emptyForm })

// 表单验证规则
const formRules: FormRules = {
  name: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' }
  ],
  menuType: [
    { required: true, message: '请选择菜单类型', trigger: 'change' }
  ],
  routePath: [
    {
      validator: (rule, value, callback) => {
        if (formModel.menuType === 'BUTTON') {
          callback() // 按钮类型不需要路由路径
          return
        }
        if (!value) {
          callback(new Error('请输入路由路径'))
          return
        }
        if (!validateRoutePath(value)) {
          callback(new Error('路由路径格式不正确，必须以/开头'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  sort: [
    { required: true, message: '请输入显示排序', trigger: 'blur' }
  ]
}

// 图标选项
const iconOptions = [
  { label: '首页', value: 'House' },
  { label: '设置', value: 'Setting' },
  { label: '用户', value: 'User' },
  { label: '用户组', value: 'UserFilled' },
  { label: '菜单', value: 'Menu' },
  { label: '文档', value: 'Document' },
  { label: '监控', value: 'Monitor' },
  { label: '查看', value: 'View' },
  { label: '连接', value: 'Connection' },
  { label: '网格', value: 'Grid' },
  { label: '文件夹', value: 'Folder' },
  { label: '文件', value: 'Files' },
  { label: '数据面板', value: 'DataBoard' },
  { label: '管理', value: 'Management' }
]

// 图标组件映射
const iconComponents = {
  House,
  Setting,
  User,
  UserFilled,
  Menu,
  Document,
  Monitor,
  View,
  Connection,
  Grid,
  Folder,
  Files,
  DataBoard,
  Management
}

// 获取图标组件
const getIconComponent = (iconName: string) => {
  return iconComponents[iconName as keyof typeof iconComponents] || Setting
}

// 计算属性 - 搜索过滤
const filteredTableData = computed(() => {
  if (!query.keyword) return tableData.value

  const filterData = (items: MenuItem[]): MenuItem[] => {
    const result: MenuItem[] = []

    for (const item of items) {
      const matchesKeyword = item.name.toLowerCase().includes(query.keyword.toLowerCase())
      const filteredChildren = item.children ? filterData(item.children) : []

      if (matchesKeyword || filteredChildren.length > 0) {
        result.push({
          ...item,
          children: filteredChildren.length > 0 ? filteredChildren : item.children
        })
      }
    }

    return result
  }

  return filterData(tableData.value)
})

// 业务方法
const fetchMenuData = async () => {
  loading.value = true
  try {
    // 检查登录状态
    const token = localStorage.getItem('token')
    console.log('🔍 检查登录状态:', token ? '已登录' : '未登录')

    if (!token || token === 'null' || token === 'undefined') {
      ElMessage.warning('登录状态已过期，请重新登录')
      // 可以选择跳转到登录页
      // window.location.href = '#/login'
      return
    }

            const response = await getMenuNodes()

    // 处理响应数据 - 优先使用API数据，失败则用模拟数据
    let rawData: any[] = []

    if (response.data?.data && Array.isArray(response.data.data)) {
      rawData = response.data.data
    } else if (response.data && Array.isArray(response.data)) {
      rawData = response.data
    } else {
      // API数据格式异常，使用模拟数据
      rawData = [
        {
          id: 1,
          menuType: 'DIRECTORY',
          parentId: 0,
          name: '系统管理',
          routePath: '/system',
          component: 'Layout',
          permissions: 'system',
          archive: false,
          icon: 'Setting',
          redirect: '/system/user',
          isShow: true,
          sort: 1,
          children: [
            {
              id: 2,
              menuType: 'MENU',
              parentId: 1,
              name: '用户管理',
              routePath: '/system/user',
              component: '@/views/system/user/index.vue',
              permissions: 'system:user:view',
              archive: false,
              icon: 'User',
              redirect: '',
              isShow: true,
              sort: 1
            },
            {
              id: 4,
              menuType: 'MENU',
              parentId: 1,
              name: '菜单管理',
              routePath: '/system/menu',
              component: '@/views/system/menu/index.vue',
              permissions: 'system:menu:view',
              archive: false,
              icon: 'Menu',
              redirect: '',
              isShow: true,
              sort: 3
            }
          ]
        },
        {
          id: 5,
          menuType: 'MENU',
          parentId: 0,
          name: '首页',
          routePath: '/dashboard',
          component: '@/views/Dashboard/index.vue',
          permissions: 'dashboard:view',
          archive: false,
          icon: 'House',
          redirect: '',
          isShow: true,
          sort: 0
        }
      ]
    }

        // 直接设置表格数据（不使用复杂的树形构建）
    tableData.value = rawData

    if (tableData.value.length === 0) {
      ElMessage.info('暂无菜单数据')
    }
  } catch (error: any) {
    console.error('获取菜单数据失败:', error)

    // 特别处理401错误
    if (error.response?.status === 401) {
      ElMessage.error('登录已过期，请重新登录')
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
      setTimeout(() => {
        window.location.href = '#/login'
      }, 2000)
    } else {
      ElMessage.error('获取菜单数据失败，请刷新重试')
    }

    // 设置空数据避免页面错误
    tableData.value = []
  } finally {
    loading.value = false
  }
}

const fetchParentMenuOptions = async () => {
  try {
    parentMenuOptions.value = await getParentMenuOptions()
  } catch (error) {
    console.error('获取父级菜单选项失败:', error)
  }
}

const handleSearch = () => {
  // 搜索功能通过计算属性实现
}

const handleReset = () => {
  query.keyword = ''
}

const refreshTable = () => {
  fetchMenuData()
}

const toggleExpandAll = () => {
  isExpandAll.value = !isExpandAll.value
}

const handleSelectionChange = (selection: MenuItem[]) => {
  selectedIds.value = selection.map(item => item.id || 0).filter(id => id > 0)
}

const handleAdd = () => {
  Object.assign(formModel, { ...emptyForm })
  formModel.parentId = 0
  isAdd.value = true
  dialogTitle.value = '新增菜单'
  dialogVisible.value = true
  fetchParentMenuOptions()
}

const handleAddChild = (row: MenuItem) => {
  Object.assign(formModel, { ...emptyForm })
  formModel.parentId = row.id || 0
  isAdd.value = true
  dialogTitle.value = `新增子菜单 - ${row.name}`
  dialogVisible.value = true
  fetchParentMenuOptions()
}

const handleEdit = (row: MenuItem) => {
  Object.assign(formModel, transformToFormData(row))
  isAdd.value = false
  dialogTitle.value = '编辑菜单'
  dialogVisible.value = true
  fetchParentMenuOptions()
}

const handleSave = async () => {
  try {
    await formRef.value?.validate()

    saveLoading.value = true

    if (isAdd.value) {
      await addMenu(formModel)
      ElMessage.success('新增成功')
    } else {
      await updateMenu(formModel)
      ElMessage.success('编辑成功')
    }

    dialogVisible.value = false
    refreshTable()
  } catch (error) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败')
  } finally {
    saveLoading.value = false
  }
}

const handleCancel = () => {
  dialogVisible.value = false
  formRef.value?.resetFields()
}

const handleDelete = async (row: MenuItem) => {
  if (row.children && row.children.length > 0) {
    ElMessage.warning('该菜单包含子菜单，请先删除子菜单')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除菜单"${row.name}"吗？`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await deleteMenu(row.id || 0)
    ElMessage.success('删除成功')
    refreshTable()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

const handleBatchDelete = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedIds.value.length} 个菜单吗？`,
      '批量删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await batchDeleteMenus(selectedIds.value)
    ElMessage.success('批量删除成功')
    selectedIds.value = []
    refreshTable()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败')
    }
  }
}

const handleShowChange = async (row: MenuItem) => {
  try {
    // 调用更新显示状态的API
    await updateMenu({
      id: row.id,
      menuType: row.menuType || 'MENU',
      parentId: row.parentId || 0,
      name: row.name,
      routePath: row.routePath || '',
      component: row.component || '',
      permissions: row.permissions || '',
      archive: row.archive || false,
      icon: row.icon || '',
      redirect: row.redirect || '',
      isShow: row.isShow,
      sort: row.sort || 0
    })
    ElMessage.success('显示状态更新成功')
  } catch (error) {
    console.error('显示状态更新失败:', error)
    ElMessage.error('显示状态更新失败')
    // 恢复原状态
    row.isShow = !row.isShow
  }
}

const handleSortChange = async (row: MenuItem) => {
  try {
    // 调用更新排序的API
    await updateMenu({
      id: row.id,
      menuType: row.menuType || 'MENU',
      parentId: row.parentId || 0,
      name: row.name,
      routePath: row.routePath || '',
      component: row.component || '',
      permissions: row.permissions || '',
      archive: row.archive || false,
      icon: row.icon || '',
      redirect: row.redirect || '',
      isShow: row.isShow || true,
      sort: row.sort || 0
    })
    ElMessage.success('排序更新成功')
    // 重新获取数据以保持排序
    setTimeout(() => refreshTable(), 300)
  } catch (error) {
    console.error('排序更新失败:', error)
    ElMessage.error('排序更新失败')
  }
}

// 路由路径失焦时自动生成组件路径
const handleRoutePathBlur = () => {
  if (formModel.routePath && !formModel.component && formModel.menuType === 'MENU') {
    formModel.component = generateDefaultComponent(formModel.routePath)
  }
}

// 自动生成组件路径
const autoGenerateComponent = () => {
  if (formModel.routePath) {
    formModel.component = generateDefaultComponent(formModel.routePath)
  } else {
    ElMessage.warning('请先输入路由路径')
  }
}

// 生命周期
onMounted(() => {
  fetchMenuData()
})

// 导出方法供模板使用
defineExpose({
  refreshTable,
  getMenuTypeText,
  getMenuTypeTagType
})
</script>

<style scoped>
.menu-management {
  padding: 20px;
}

.toolbar {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  gap: 8px;
  align-items: center;
}

.menu-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.menu-icon {
  color: #409eff;
}

/* 表格样式优化 */
:deep(.el-table .el-table__row) {
  transition: background-color 0.3s;
}

:deep(.el-table .el-table__row:hover) {
  background-color: #f5f7fa;
}

/* 对话框样式 */
:deep(.el-dialog__body) {
  padding: 20px 20px 0;
}

/* 树形选择器样式 */
:deep(.el-tree-select .el-tree-node__content) {
  padding: 0 8px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .menu-management {
    padding: 10px;
  }

  .toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .toolbar-left,
  .toolbar-right {
    flex-wrap: wrap;
    justify-content: center;
  }
}
</style>
